package com.ddw.meedeeuh.views;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.text.DecimalFormat;

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.CompoundBorder;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.basic.BasicTabbedPaneUI;

import com.ddw.meedeeuh.presenters.MovieEditorPresenter.MovieEditorTabType;
import com.ddw.meedeeuh.presenters.MovieEditorPresenter.MovieEditorView;
import com.ddw.meedeeuh.shared.io.SourceFile;
import com.ddw.meedeeuh.shared.io.SourceFolder;
import com.ddw.meedeeuh.shared.movie.Actor;
import com.ddw.meedeeuh.shared.movie.ExtraThumb;
import com.ddw.meedeeuh.shared.movie.StreamDetails;

@SuppressWarnings("serial")
public class MovieEditorViewImpl extends JTabbedPane implements MovieEditorView {

	private static final DecimalFormat YEAR_FORMAT = new DecimalFormat("####");
	private static final DecimalFormat RATING_FORMAT = new DecimalFormat("#.######");
	private static final DecimalFormat INTEGER_FORMAT = new DecimalFormat("#");
	private final JTextField fieldName = new JTextField();
	private final JFormattedTextField fieldYear = new JFormattedTextField(YEAR_FORMAT);
	private final JTextField fieldOriginalTitle = new JTextField();
	private final JTextField fieldSortTitle = new JTextField();
	private final JTextField fieldSet = new JTextField();
	private final JFormattedTextField fieldRating = new JFormattedTextField(RATING_FORMAT);
	private final JFormattedTextField fieldVotes = new JFormattedTextField(INTEGER_FORMAT);
	private final JFormattedTextField fieldRuntime = new JFormattedTextField(INTEGER_FORMAT);
	private final JTextField fieldMpaa = new JTextField();
	private final JFormattedTextField fieldPlaycount = new JFormattedTextField(INTEGER_FORMAT);
	private final JTextField fieldImdbId = new JTextField();
	private final JTextField fieldTrailer = new JTextField();
	private final JTextField fieldGenre = new JTextField();
	private final JTextField fieldDirector = new JTextField();
	private final JTextArea areaOutline = new JTextArea();
	private final JTextArea areaPlot = new JTextArea();
	private final JTextArea areaTagline = new JTextArea();
	private final JTextArea areaNfo = new JTextArea();
	private final JTextArea areaNewNfo = new JTextArea();

	public MovieEditorViewImpl() {
		super(JTabbedPane.TOP, JTabbedPane.SCROLL_TAB_LAYOUT);

		// Set style
		setOpaque(true);
		setUI(new BasicTabbedPaneUI() {

			@Override
			protected void installDefaults() {
				super.installDefaults();

				this.tabInsets = new Insets(2, 5, 2, 5);
				this.contentBorderInsets = new Insets(1, 1, 1, 1);
			}

		});

		addInfoTab();
		addMediaTab();
		addPosterTab();
		addFanartTab();
		addExtraThumbsTab();
		addNfoTab();
	}

	private void addInfoTab() {
		final JPanel panelSingleLine = new JPanel(new GridLayout(0, 2, 5, 5));

		fieldName.setPreferredSize(new Dimension(100, 20));
		Field.applyFieldStyle(fieldName);
		panelSingleLine.add(new Field("Title", fieldName));

		fieldYear.setColumns(4);
		Field.applyFieldStyle(fieldYear);
		panelSingleLine.add(new Field("Year", fieldYear, true));

		fieldOriginalTitle.setPreferredSize(new Dimension(100, 20));
		Field.applyFieldStyle(fieldOriginalTitle);
		panelSingleLine.add(new Field("Original Title", fieldOriginalTitle));

		fieldSortTitle.setPreferredSize(new Dimension(100, 20));
		Field.applyFieldStyle(fieldSortTitle);
		panelSingleLine.add(new Field("Sort Title", fieldSortTitle));

		fieldSet.setPreferredSize(new Dimension(100, 20));
		Field.applyFieldStyle(fieldSet);
		panelSingleLine.add(new Field("Movie Set", fieldSet));

		fieldRating.setColumns(6);
		Field.applyFieldStyle(fieldRating);
		panelSingleLine.add(new Field("Rating", fieldRating, true));

		fieldVotes.setColumns(6);
		Field.applyFieldStyle(fieldVotes);
		panelSingleLine.add(new Field("Votes", fieldVotes, true));

		fieldRuntime.setColumns(6);
		Field.applyFieldStyle(fieldRuntime);
		panelSingleLine.add(new Field("Runtime", fieldRuntime, true));

		fieldMpaa.setPreferredSize(new Dimension(100, 20));
		Field.applyFieldStyle(fieldMpaa);
		panelSingleLine.add(new Field("MPAA", fieldMpaa));

		fieldPlaycount.setColumns(6);
		Field.applyFieldStyle(fieldPlaycount);
		panelSingleLine.add(new Field("Play Count", fieldPlaycount, true));

		fieldImdbId.setPreferredSize(new Dimension(100, 20));
		Field.applyFieldStyle(fieldImdbId);
		panelSingleLine.add(new Field("IMDB ID", fieldImdbId));

		fieldTrailer.setPreferredSize(new Dimension(100, 20));
		Field.applyFieldStyle(fieldTrailer);
		panelSingleLine.add(new Field("Trailer", fieldTrailer));

		fieldGenre.setPreferredSize(new Dimension(100, 20));
		Field.applyFieldStyle(fieldGenre);
		panelSingleLine.add(new Field("Genre", fieldGenre));

		fieldDirector.setPreferredSize(new Dimension(100, 20));
		Field.applyFieldStyle(fieldDirector);
		panelSingleLine.add(new Field("Director", fieldDirector));

		final JPanel panelMultiLine = new JPanel(new GridLayout(0, 1, 5, 5));

		final JScrollPane areaTaglineScroll = Field.createScrollableTextArea(areaTagline);
		areaTaglineScroll.setPreferredSize(new Dimension(200, 60));
		panelMultiLine.add(new Field("Tag Line", areaTaglineScroll));

		final JScrollPane areaOutlineScroll = Field.createScrollableTextArea(areaOutline);
		areaOutlineScroll.setPreferredSize(new Dimension(200, 60));
		panelMultiLine.add(new Field("Outline", areaOutlineScroll));

		final JScrollPane areaPlotScroll = Field.createScrollableTextArea(areaPlot);
		areaPlotScroll.setPreferredSize(new Dimension(200, 60));
		panelMultiLine.add(new Field("Plot", areaPlotScroll));

		final JPanel container = new JPanel(new GridBagLayout());
		GridBagConstraints gbc;

		// Configure top panel with text boxes
		gbc = new GridBagConstraints();
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.anchor = GridBagConstraints.NORTHWEST;
		gbc.weightx = 1.0;
		gbc.gridx = gbc.gridy = 0;
		container.add(panelSingleLine, gbc);

		// Configure middle panel with multi line text boxes
		gbc = new GridBagConstraints();
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.anchor = GridBagConstraints.NORTHWEST;
		gbc.gridx = 0;
		gbc.gridy = 1;
		container.add(panelMultiLine, gbc);

		// Eat up the remaining space
		gbc = new GridBagConstraints();
		gbc.fill = GridBagConstraints.BOTH;
		gbc.anchor = GridBagConstraints.SOUTH;
		gbc.weightx = gbc.weighty = 1.0;
		gbc.gridx = 0;
		gbc.gridy = 2;
		container.add(new JPanel(), gbc);

		// Create the information tab
		addTab("Info", new JScrollPane(container));
	}

	private void addMediaTab() {
		addTab("Media", new JScrollPane(new JPanel()));
	}

	private void addPosterTab() {
		addTab("Poster", new JScrollPane(new JPanel()));
	}

	private void addFanartTab() {
		addTab("Fanart", new JScrollPane(new JPanel()));
	}

	private void addExtraThumbsTab() {
		addTab("Extra Thumbs", new JScrollPane(new JPanel()));
	}

	private void addNfoTab() {
		final JPanel panelMultiLine = new JPanel(new GridLayout(0, 1, 5, 5));

		areaNfo.setEditable(false);
		areaNfo.setFont(Font.decode(Font.MONOSPACED));
		areaNfo.setBackground(new Color(200, 200, 200));
		final JScrollPane areaNfoScroll = Field.createScrollableTextArea(areaNfo);
		areaNfoScroll.setPreferredSize(new Dimension(200, 120));
		panelMultiLine.add(new Field("Current NFO", areaNfoScroll));

		areaNewNfo.setEditable(false);
		areaNewNfo.setFont(Font.decode(Font.MONOSPACED));
		areaNewNfo.setBackground(new Color(200, 200, 200));
		final JScrollPane areaNewNfoScroll = Field.createScrollableTextArea(areaNewNfo);
		areaNewNfoScroll.setPreferredSize(new Dimension(200, 120));
		panelMultiLine.add(new Field("New NFO", areaNewNfoScroll));

		final JPanel container = new JPanel(new GridBagLayout());
		GridBagConstraints gbc;

		// Configure top panel with multi line text boxes
		gbc = new GridBagConstraints();
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.anchor = GridBagConstraints.NORTHWEST;
		gbc.gridx = 0;
		gbc.gridy = 1;
		container.add(panelMultiLine, gbc);

		// Eat up the remaining space
		gbc = new GridBagConstraints();
		gbc.fill = GridBagConstraints.BOTH;
		gbc.anchor = GridBagConstraints.SOUTH;
		gbc.weightx = gbc.weighty = 1.0;
		gbc.gridx = 0;
		gbc.gridy = 2;
		container.add(new JPanel(), gbc);

		// Create the information tab
		addTab("NFO", new JScrollPane(container));
	}

	@Override
	public Component asComponent() {
		return this;
	}

	@Override
	public void setName(String name) {
		this.fieldName.setText(name);
	}

	@Override
	public void setYear(Integer year) {
		this.fieldYear.setValue(year);
	}

	@Override
	public void setOriginalTitle(String originalTitle) {
		this.fieldOriginalTitle.setText(originalTitle);
	}

	@Override
	public void setSortTitle(String sortTitle) {
		this.fieldSortTitle.setText(sortTitle);
	}

	@Override
	public void setSet(String set) {
		this.fieldSet.setText(set);
	}

	@Override
	public void setRating(Double rating) {
		this.fieldRating.setValue(rating);
	}

	@Override
	public void setTop250(Boolean top250) {
		// TODO Auto-generated method stub

	}

	@Override
	public void setVotes(Integer votes) {
		this.fieldVotes.setValue(votes);
	}

	@Override
	public void setOutline(String outline) {
		this.areaOutline.setText(outline);
	}

	@Override
	public void setPlot(String plot) {
		this.areaPlot.setText(plot);
	}

	@Override
	public void setTagLine(String tagline) {
		this.areaTagline.setText(tagline);
	}

	@Override
	public void setRuntime(Integer runtime) {
		this.fieldRuntime.setValue(runtime);
	}

	@Override
	public void setThumbnail(String thumbnail) {
		// TODO
	}

	@Override
	public void setMpaa(String mpaa) {
		this.fieldMpaa.setText(mpaa);
	}

	@Override
	public void setPlayCount(Integer playCount) {
		this.fieldPlaycount.setValue(playCount);
	}

	@Override
	public void setWatched(Boolean watched) {
		// TODO Auto-generated method stub

	}

	@Override
	public void setImdbId(String imdbId) {
		this.fieldImdbId.setText(imdbId);
	}

	@Override
	public void setTrailer(String trailer) {
		this.fieldTrailer.setText(trailer);
	}

	@Override
	public void setGenre(String genre) {
		this.fieldGenre.setText(genre);
	}

	@Override
	public void setCredits(String credits) {
		// TODO Auto-generated method stub

	}

	@Override
	public void setNfo(SourceFile nfo) {
		// TODO Auto-generated method stub

	}

	@Override
	public void setPoster(SourceFile poster) {
		// TODO Auto-generated method stub

	}

	@Override
	public void setFanart(SourceFile fanart) {
		// TODO Auto-generated method stub

	}

	@Override
	public void clearStreamDetails() {
		// TODO Auto-generated method stub

	}

	@Override
	public void addStreamDetail(StreamDetails streamDetails) {
		// TODO Auto-generated method stub

	}

	@Override
	public void removeStreamDetail(StreamDetails streamDetails) {
		// TODO Auto-generated method stub

	}

	@Override
	public void setDirector(String director) {
		this.fieldDirector.setText(director);
	}

	@Override
	public void clearActors() {
		// TODO Auto-generated method stub

	}

	@Override
	public void addActor(Actor actor) {
		// TODO Auto-generated method stub

	}

	@Override
	public void removeActor(Actor actor) {
		// TODO Auto-generated method stub

	}

	@Override
	public void clearExtraThumbs() {
		// TODO Auto-generated method stub

	}

	@Override
	public void addExtraThumb(ExtraThumb extraThumb) {
		// TODO Auto-generated method stub

	}

	@Override
	public void removeExtraThumb(ExtraThumb extraThumb) {
		// TODO Auto-generated method stub

	}

	@Override
	public String getName() {
		return this.fieldName.getText();
	}

	@Override
	public Integer getYear() {
		return (Integer) this.fieldYear.getValue();
	}

	@Override
	public String getOriginalTitle() {
		return this.fieldOriginalTitle.getText();
	}

	@Override
	public String getSortTitle() {
		return this.fieldSortTitle.getText();
	}

	@Override
	public String getSet() {
		return this.fieldSet.getText();
	}

	@Override
	public Double getRating() {
		return (Double) this.fieldRating.getValue();
	}

	@Override
	public Boolean isTop250() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Integer getVotes() {
		return (Integer) this.fieldVotes.getValue();
	}

	@Override
	public String getOutline() {
		return this.areaOutline.getText();
	}

	@Override
	public String getPlot() {
		return this.areaPlot.getText();
	}

	@Override
	public String getTagLine() {
		return this.areaTagline.getText();
	}

	@Override
	public Integer getRuntime() {
		return (Integer) this.fieldRuntime.getValue();
	}

	@Override
	public String getThumbnail() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getMpaa() {
		return this.fieldMpaa.getText();
	}

	@Override
	public Integer getPlayCount() {
		return (Integer) this.fieldPlaycount.getValue();
	}

	@Override
	public Boolean isWatched() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getImdbId() {
		return this.fieldImdbId.getText();
	}

	@Override
	public String getTrailer() {
		return this.fieldTrailer.getText();
	}

	@Override
	public String getGenre() {
		return this.fieldGenre.getText();
	}

	@Override
	public String getCredits() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Iterable<? extends StreamDetails> getStreamDetails() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getDirector() {
		return this.fieldDirector.getText();
	}

	@Override
	public SourceFolder getFolder() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public SourceFile getNfo() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public SourceFile getPoster() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public SourceFile getFanart() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Iterable<? extends Actor> getActors() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Iterable<? extends ExtraThumb> getExtraThumbs() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int getStreamDetailsCount() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int getActorsCount() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int getExtraThumbsCount() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public MovieEditorTabType getSelectedTab() {
		switch(getSelectedIndex()) {
			case 0:
				return MovieEditorTabType.INFO;
			case 1:
				return MovieEditorTabType.MEDIA;
			case 2:
				return MovieEditorTabType.POSTER;
			case 3:
				return MovieEditorTabType.FANART;
			case 4:
				return MovieEditorTabType.EXTRATHUMBS;
			case 5:
				return MovieEditorTabType.NFO;
			default:
				throw new RuntimeException("Unhandled tab index, cannot determine tab type");
		}
	}

	@Override
	public void addTabChangeListener(ChangeListener listener) {
		addChangeListener(listener);
	}

	@Override
	public void setNfoText(String nfo) {
		this.areaNfo.setText(nfo);
	}

	@Override
	public void setNewNfoText(String nfo) {
		this.areaNewNfo.setText(nfo);
	}

	private static class Field extends JPanel {

		public Field(String label, JComponent field) {
			this(label, field, false);
		}

		public Field(String label, JComponent field, boolean absoluteWidth) {
			super(new GridBagLayout());
			GridBagConstraints gbc;

			final JLabel l = new JLabel(label);
			l.setPreferredSize(new Dimension(80, 20));
			gbc = new GridBagConstraints();
			gbc.anchor = GridBagConstraints.WEST;
			gbc.gridx = gbc.gridy = 0;
			gbc.insets = new Insets(5, 5, 5, 5);
			gbc.ipadx = gbc.ipady = 5;
			add(l, gbc);

			gbc = new GridBagConstraints();
			gbc.anchor = GridBagConstraints.WEST;
			gbc.gridx = 1;
			gbc.gridy = 0;
			gbc.insets = new Insets(5, 5, 5, 5);
			gbc.ipadx = gbc.ipady = 7;

			if(absoluteWidth == false) {
				gbc.fill = GridBagConstraints.HORIZONTAL;
				gbc.weightx = 1.0;
			}

			add(field, gbc);

			if(absoluteWidth) {
				gbc.fill = GridBagConstraints.HORIZONTAL;
				gbc.weightx = 1.0;
				add(new JPanel(), gbc);
			}
		}

		public static void applyFieldStyle(JComponent componentToStyle) {
			componentToStyle.setBorder(new CompoundBorder(BorderFactory.createEtchedBorder(),
					BorderFactory.createEmptyBorder(0, 5, 0, 5)));
		}

		public static JScrollPane createScrollableTextArea(JTextArea textArea) {
			textArea.setLineWrap(true);
			textArea.setWrapStyleWord(true);
			textArea.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
			final JScrollPane scroll = new JScrollPane(textArea);
			scroll.setBorder(new CompoundBorder(BorderFactory.createEtchedBorder(),
					BorderFactory.createEmptyBorder(0, 0, 0, 0)));
			return scroll;
		}

	}

}
